home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / A_bitmap.asm < prev    next >
Encoding:
Assembly Source File  |  2001-03-20  |  30.2 KB  |  1,221 lines

  1. ;    VirtualDub - Video processing and capture application
  2. ;    Copyright (C) 1998-2001 Avery Lee
  3. ;
  4. ;    This program is free software; you can redistribute it and/or modify
  5. ;    it under the terms of the GNU General Public License as published by
  6. ;    the Free Software Foundation; either version 2 of the License, or
  7. ;    (at your option) any later version.
  8. ;
  9. ;    This program is distributed in the hope that it will be useful,
  10. ;    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ;    GNU General Public License for more details.
  13. ;
  14. ;    You should have received a copy of the GNU General Public License
  15. ;    along with this program; if not, write to the Free Software
  16. ;    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.     .586
  19.     .mmx
  20.     .model    flat
  21.  
  22.     extern    _MMX_enabled:byte
  23.     extern    _FPU_enabled:byte
  24.  
  25.     .const
  26.  
  27. bilinFPU_tbl    real4    256.0,  0.0,  0.0,  0.0,240.0, 16.0,  0.0,  0.0,224.0, 32.0,  0.0,  0.0,208.0, 48.0,  0.0,  0.0
  28.     real4    192.0, 64.0,  0.0,  0.0,176.0, 80.0,  0.0,  0.0,160.0, 96.0,  0.0,  0.0,144.0,112.0,  0.0,  0.0
  29.     real4    128.0,128.0,  0.0,  0.0,112.0,144.0,  0.0,  0.0, 96.0,160.0,  0.0,  0.0, 80.0,176.0,  0.0,  0.0
  30.     real4     64.0,192.0,  0.0,  0.0, 48.0,208.0,  0.0,  0.0, 32.0,224.0,  0.0,  0.0, 16.0,240.0,  0.0,  0.0
  31.  
  32.     real4    240.0,  0.0, 16.0,  0.0,225.0, 15.0, 15.0,  1.0,210.0, 30.0, 14.0,  2.0,195.0, 45.0, 13.0,  3.0
  33.     real4    180.0, 60.0, 12.0,  4.0,165.0, 75.0, 11.0,  5.0,150.0, 90.0, 10.0,  6.0,135.0,105.0,  9.0,  7.0
  34.     real4    120.0,120.0,  8.0,  8.0,105.0,135.0,  7.0,  9.0, 90.0,150.0,  6.0, 10.0, 75.0,165.0,  5.0, 11.0
  35.     real4     60.0,180.0,  4.0, 12.0, 45.0,195.0,  3.0, 13.0, 30.0,210.0,  2.0, 14.0, 15.0,225.0,  1.0, 15.0
  36.  
  37.     real4    224.0,  0.0, 32.0,  0.0,210.0, 14.0, 30.0,  2.0,196.0, 28.0, 28.0,  4.0,182.0, 42.0, 26.0,  6.0
  38.     real4    168.0, 56.0, 24.0,  8.0,154.0, 70.0, 22.0, 10.0,140.0, 84.0, 20.0, 12.0,126.0, 98.0, 18.0, 14.0
  39.     real4    112.0,112.0, 16.0, 16.0, 98.0,126.0, 14.0, 18.0, 84.0,140.0, 12.0, 20.0, 70.0,154.0, 10.0, 22.0
  40.     real4     56.0,168.0,  8.0, 24.0, 42.0,182.0,  6.0, 26.0, 28.0,196.0,  4.0, 28.0, 14.0,210.0,  2.0, 30.0
  41.  
  42.     real4    208.0,  0.0, 48.0,  0.0,195.0, 13.0, 45.0,  3.0,182.0, 26.0, 42.0,  6.0,169.0, 39.0, 39.0,  9.0
  43.     real4    156.0, 52.0, 36.0, 12.0,143.0, 65.0, 33.0, 15.0,130.0, 78.0, 30.0, 18.0,117.0, 91.0, 27.0, 21.0
  44.     real4    104.0,104.0, 24.0, 24.0, 91.0,117.0, 21.0, 27.0, 78.0,130.0, 18.0, 30.0, 65.0,143.0, 15.0, 33.0
  45.     real4     52.0,156.0, 12.0, 36.0, 39.0,169.0,  9.0, 39.0, 26.0,182.0,  6.0, 42.0, 13.0,195.0,  3.0, 45.0
  46.  
  47.     real4    192.0,  0.0, 64.0,  0.0,180.0, 12.0, 60.0,  4.0,168.0, 24.0, 56.0,  8.0,156.0, 36.0, 52.0, 12.0
  48.     real4    144.0, 48.0, 48.0, 16.0,132.0, 60.0, 44.0, 20.0,120.0, 72.0, 40.0, 24.0,108.0, 84.0, 36.0, 28.0
  49.     real4     96.0, 96.0, 32.0, 32.0, 84.0,108.0, 28.0, 36.0, 72.0,120.0, 24.0, 40.0, 60.0,132.0, 20.0, 44.0
  50.     real4     48.0,144.0, 16.0, 48.0, 36.0,156.0, 12.0, 52.0, 24.0,168.0,  8.0, 56.0, 12.0,180.0,  4.0, 60.0
  51.  
  52.     real4    176.0,  0.0, 80.0,  0.0,165.0, 11.0, 75.0,  5.0,154.0, 22.0, 70.0, 10.0,143.0, 33.0, 65.0, 15.0
  53.     real4    132.0, 44.0, 60.0, 20.0,121.0, 55.0, 55.0, 25.0,110.0, 66.0, 50.0, 30.0, 99.0, 77.0, 45.0, 35.0
  54.     real4     88.0, 88.0, 40.0, 40.0, 77.0, 99.0, 35.0, 45.0, 66.0,110.0, 30.0, 50.0, 55.0,121.0, 25.0, 55.0
  55.     real4     44.0,132.0, 20.0, 60.0, 33.0,143.0, 15.0, 65.0, 22.0,154.0, 10.0, 70.0, 11.0,165.0,  5.0, 75.0
  56.  
  57.     real4    160.0,  0.0, 96.0,  0.0,150.0, 10.0, 90.0,  6.0,140.0, 20.0, 84.0, 12.0,130.0, 30.0, 78.0, 18.0
  58.     real4    120.0, 40.0, 72.0, 24.0,110.0, 50.0, 66.0, 30.0,100.0, 60.0, 60.0, 36.0, 90.0, 70.0, 54.0, 42.0
  59.     real4     80.0, 80.0, 48.0, 48.0, 70.0, 90.0, 42.0, 54.0, 60.0,100.0, 36.0, 60.0, 50.0,110.0, 30.0, 66.0
  60.     real4     40.0,120.0, 24.0, 72.0, 30.0,130.0, 18.0, 78.0, 20.0,140.0, 12.0, 84.0, 10.0,150.0,  6.0, 90.0
  61.  
  62.     real4    144.0,  0.0,112.0,  0.0,135.0,  9.0,105.0,  7.0,126.0, 18.0, 98.0, 14.0,117.0, 27.0, 91.0, 21.0
  63.     real4    108.0, 36.0, 84.0, 28.0, 99.0, 45.0, 77.0, 35.0, 90.0, 54.0, 70.0, 42.0, 81.0, 63.0, 63.0, 49.0
  64.     real4     72.0, 72.0, 56.0, 56.0, 63.0, 81.0, 49.0, 63.0, 54.0, 90.0, 42.0, 70.0, 45.0, 99.0, 35.0, 77.0
  65.     real4     36.0,108.0, 28.0, 84.0, 27.0,117.0, 21.0, 91.0, 18.0,126.0, 14.0, 98.0,  9.0,135.0,  7.0,105.0
  66.  
  67.     real4    128.0,  0.0,128.0,  0.0,120.0,  8.0,120.0,  8.0,112.0, 16.0,112.0, 16.0,104.0, 24.0,104.0, 24.0
  68.     real4     96.0, 32.0, 96.0, 32.0, 88.0, 40.0, 88.0, 40.0, 80.0, 48.0, 80.0, 48.0, 72.0, 56.0, 72.0, 56.0
  69.     real4     64.0, 64.0, 64.0, 64.0, 56.0, 72.0, 56.0, 72.0, 48.0, 80.0, 48.0, 80.0, 40.0, 88.0, 40.0, 88.0
  70.     real4     32.0, 96.0, 32.0, 96.0, 24.0,104.0, 24.0,104.0, 16.0,112.0, 16.0,112.0,  8.0,120.0,  8.0,120.0
  71.  
  72.     real4    112.0,  0.0,144.0,  0.0,105.0,  7.0,135.0,  9.0, 98.0, 14.0,126.0, 18.0, 91.0, 21.0,117.0, 27.0
  73.     real4     84.0, 28.0,108.0, 36.0, 77.0, 35.0, 99.0, 45.0, 70.0, 42.0, 90.0, 54.0, 63.0, 49.0, 81.0, 63.0
  74.     real4     56.0, 56.0, 72.0, 72.0, 49.0, 63.0, 63.0, 81.0, 42.0, 70.0, 54.0, 90.0, 35.0, 77.0, 45.0, 99.0
  75.     real4     28.0, 84.0, 36.0,108.0, 21.0, 91.0, 27.0,117.0, 14.0, 98.0, 18.0,126.0,  7.0,105.0,  9.0,135.0
  76.  
  77.     real4     96.0,  0.0,160.0,  0.0, 90.0,  6.0,150.0, 10.0, 84.0, 12.0,140.0, 20.0, 78.0, 18.0,130.0, 30.0
  78.     real4     72.0, 24.0,120.0, 40.0, 66.0, 30.0,110.0, 50.0, 60.0, 36.0,100.0, 60.0, 54.0, 42.0, 90.0, 70.0
  79.     real4     48.0, 48.0, 80.0, 80.0, 42.0, 54.0, 70.0, 90.0, 36.0, 60.0, 60.0,100.0, 30.0, 66.0, 50.0,110.0
  80.     real4     24.0, 72.0, 40.0,120.0, 18.0, 78.0, 30.0,130.0, 12.0, 84.0, 20.0,140.0,  6.0, 90.0, 10.0,150.0
  81.  
  82.     real4     80.0,  0.0,176.0,  0.0, 75.0,  5.0,165.0, 11.0, 70.0, 10.0,154.0, 22.0, 65.0, 15.0,143.0, 33.0
  83.     real4     60.0, 20.0,132.0, 44.0, 55.0, 25.0,121.0, 55.0, 50.0, 30.0,110.0, 66.0, 45.0, 35.0, 99.0, 77.0
  84.     real4     40.0, 40.0, 88.0, 88.0, 35.0, 45.0, 77.0, 99.0, 30.0, 50.0, 66.0,110.0, 25.0, 55.0, 55.0,121.0
  85.     real4     20.0, 60.0, 44.0,132.0, 15.0, 65.0, 33.0,143.0, 10.0, 70.0, 22.0,154.0,  5.0, 75.0, 11.0,165.0
  86.  
  87.     real4     64.0,  0.0,192.0,  0.0, 60.0,  4.0,180.0, 12.0, 56.0,  8.0,168.0, 24.0, 52.0, 12.0,156.0, 36.0
  88.     real4     48.0, 16.0,144.0, 48.0, 44.0, 20.0,132.0, 60.0, 40.0, 24.0,120.0, 72.0, 36.0, 28.0,108.0, 84.0
  89.     real4     32.0, 32.0, 96.0, 96.0, 28.0, 36.0, 84.0,108.0, 24.0, 40.0, 72.0,120.0, 20.0, 44.0, 60.0,132.0
  90.     real4     16.0, 48.0, 48.0,144.0, 12.0, 52.0, 36.0,156.0,  8.0, 56.0, 24.0,168.0,  4.0, 60.0, 12.0,180.0
  91.  
  92.     real4     48.0,  0.0,208.0,  0.0, 45.0,  3.0,195.0, 13.0, 42.0,  6.0,182.0, 26.0, 39.0,  9.0,169.0, 39.0
  93.     real4     36.0, 12.0,156.0, 52.0, 33.0, 15.0,143.0, 65.0, 30.0, 18.0,130.0, 78.0, 27.0, 21.0,117.0, 91.0
  94.     real4     24.0, 24.0,104.0,104.0, 21.0, 27.0, 91.0,117.0, 18.0, 30.0, 78.0,130.0, 15.0, 33.0, 65.0,143.0
  95.     real4     12.0, 36.0, 52.0,156.0,  9.0, 39.0, 39.0,169.0,  6.0, 42.0, 26.0,182.0,  3.0, 45.0, 13.0,195.0
  96.  
  97.     real4     32.0,  0.0,224.0,  0.0, 30.0,  2.0,210.0, 14.0, 28.0,  4.0,196.0, 28.0, 26.0,  6.0,182.0, 42.0
  98.     real4     24.0,  8.0,168.0, 56.0, 22.0, 10.0,154.0, 70.0, 20.0, 12.0,140.0, 84.0, 18.0, 14.0,126.0, 98.0
  99.     real4     16.0, 16.0,112.0,112.0, 14.0, 18.0, 98.0,126.0, 12.0, 20.0, 84.0,140.0, 10.0, 22.0, 70.0,154.0
  100.     real4      8.0, 24.0, 56.0,168.0,  6.0, 26.0, 42.0,182.0,  4.0, 28.0, 28.0,196.0,  2.0, 30.0, 14.0,210.0
  101.  
  102.     real4     16.0,  0.0,240.0,  0.0, 15.0,  1.0,225.0, 15.0, 14.0,  2.0,210.0, 30.0, 13.0,  3.0,195.0, 45.0
  103.     real4     12.0,  4.0,180.0, 60.0, 11.0,  5.0,165.0, 75.0, 10.0,  6.0,150.0, 90.0,  9.0,  7.0,135.0,105.0
  104.     real4      8.0,  8.0,120.0,120.0,  7.0,  9.0,105.0,135.0,  6.0, 10.0, 90.0,150.0,  5.0, 11.0, 75.0,165.0
  105.     real4      4.0, 12.0, 60.0,180.0,  3.0, 13.0, 45.0,195.0,  2.0, 14.0, 30.0,210.0,  1.0, 15.0, 15.0,225.0
  106.  
  107.  
  108. bilinMMX_tab1    dq    0000000000000000h
  109.         dq    0001000100010001h
  110.         dq    0002000200020002h
  111.         dq    0003000300030003h
  112.         dq    0004000400040004h
  113.         dq    0005000500050005h
  114.         dq    0006000600060006h
  115.         dq    0007000700070007h
  116.         dq    0008000800080008h
  117.         dq    0009000900090009h
  118.         dq    000a000a000a000ah
  119.         dq    000b000b000b000bh
  120.         dq    000c000c000c000ch
  121.         dq    000d000d000d000dh
  122.         dq    000e000e000e000eh
  123.         dq    000f000f000f000fh
  124.  
  125. bilinMMX_tab2    dq    0010001000100010h
  126.         dq    000f000f000f000fh
  127.         dq    000e000e000e000eh
  128.         dq    000d000d000d000dh
  129.         dq    000c000c000c000ch
  130.         dq    000b000b000b000bh
  131.         dq    000a000a000a000ah
  132.         dq    0009000900090009h
  133.         dq    0008000800080008h
  134.         dq    0007000700070007h
  135.         dq    0006000600060006h
  136.         dq    0005000500050005h
  137.         dq    0004000400040004h
  138.         dq    0003000300030003h
  139.         dq    0002000200020002h
  140.         dq    0001000100010001h
  141.  
  142. zero    dq    0000000000000000h
  143. sixteen    dq    0010001000100010h
  144.  
  145.  
  146.     .code
  147.  
  148. ;**************************************************************************
  149. ;
  150. ;asm_resize_nearest(
  151. ;    [esp+ 4] Pixel32 *dst + width,
  152. ;    [esp+ 8] Pixel32 *src,
  153. ;    [esp+12] ulong -width*4,
  154. ;    [esp+16] ulong height,
  155. ;    [esp+20] ulong srcpitch,
  156. ;    [esp+24] ulong dstpitch,
  157. ;    [esp+28] ulong xaccum,
  158. ;    [esp+32] ulong yaccum,
  159. ;    [esp+36] ulong xfrac,
  160. ;    [esp+40] ulong yfrac,
  161. ;    [esp+44] ulong xistep,
  162. ;    [esp+48] ulong yistep,
  163. ;    [esp+52] Pixel32 *precopysrc,
  164. ;    [esp+56] ulong precopy,
  165. ;    [esp+60] Pixel32 *postcopysrc,
  166. ;    [esp+64] ulong postcopy,
  167. ;    );
  168. ;
  169. ;**************************************************************************
  170.  
  171.     public    _asm_resize_nearest
  172.  
  173. _asm_resize_nearest:
  174.     push    ebp
  175.     push    edi
  176.     push    esi
  177.     push    ebx
  178.  
  179.     mov    edi,[esp+ 4+16]
  180. rowloop_nearest:
  181.     mov    ecx,[esp+56+16]        ;ecx = precopy count
  182.     mov    esi,[esp+52+16]        ;esi = precopy ptr
  183.     or    ecx,ecx
  184.     jz    rowloop_no_precopy
  185.     add    edi,[esp+12+16]
  186.     mov    eax,[esi]        ;load precopy pixel
  187.     std
  188.     sub    edi,4
  189.     rep    stosd            ;do precopy
  190.     cld
  191. rowloop_no_precopy:
  192.  
  193.     ;EAX
  194.     ;EBX    accumulator
  195.     ;ECX    fractional increment
  196.     ;EDX    integer increment
  197.     ;ESI    source
  198.     ;EDI    destination
  199.     ;EBP    loop counter
  200.  
  201.     mov    esi,[esp+ 8+16]
  202.     mov    ebp,[esp+12+16]
  203.     shr    esi,2
  204.     mov    edx,[esp+44+16]
  205.     mov    ecx,[esp+36+16]
  206.     mov    ebx,[esp+28+16]
  207.     mov    edi,[esp+ 4+16]
  208. colloop_nearest:
  209.     mov    eax,[esi*4]        ;1u
  210.     add    ebx,ecx            ;1v
  211.     adc    esi,edx            ;2u
  212.     mov    [edi+ebp],eax        ;2v
  213.     add    ebp,4            ;3u
  214.     jne    colloop_nearest        ;3v
  215.  
  216.     mov    ecx,[esp+64+16]        ;ecx = postcopy count
  217.     mov    esi,[esp+60+16]        ;esi = postcopy ptr
  218.     or    ecx,ecx
  219.     jz    rowloop_no_postcopy
  220.     mov    eax,[esi]        ;load precopy pixel
  221.     rep    stosd            ;do precopy
  222. rowloop_no_postcopy:
  223.  
  224.     mov    edi,[esp+ 4+16]
  225.  
  226.     mov    esi,[esp+ 8+16]        ;esi = source pointer
  227.     mov    ecx,[esp+52+16]        ;ecx = precopy pointer
  228.  
  229.     mov    edx,[esp+60+16]        ;edx = postcopy pointer
  230.     mov    eax,[esp+32+16]        ;get y accumulator
  231.  
  232.     add    esi,[esp+48+16]        ;add integer source bump
  233.     add    ecx,[esp+48+16]        ;add integer source bump
  234.  
  235.     add    edx,[esp+48+16]        ;add integer source bump
  236.     add    eax,[esp+40+16]        ;add y fraction
  237.  
  238.     sbb    ebx,ebx            ;ebx = -1 if need fractional step
  239.     mov    [esp+32+16],eax        ;store new y accumulator
  240.  
  241.     and    ebx,[esp+24+16]        ;ebx = fractional step
  242.     add    edi,[esp+20+16]        ;advance dest to next row
  243.  
  244.     add    esi,ebx            ;add y fractional step
  245.     add    ecx,ebx            ;add y fractional step
  246.  
  247.     add    edx,ebx            ;add y fractional step
  248.     mov    ebp,[esp+16+16]        ;get y counter
  249.  
  250.     mov    [esp+ 8+16],esi        ;store new source ptr
  251.     mov    [esp+52+16],ecx        ;store new source ptr
  252.  
  253.     mov    [esp+60+16],edx        ;store new source ptr
  254.     dec    ebp            ;decrement y counter
  255.  
  256.     mov    [esp+16+16],ebp        ;store y counter
  257.     mov    [esp+ 4+16],edi        ;store dest pointer
  258.  
  259.     jne    rowloop_nearest        ;continue until all rows done
  260.  
  261.     pop    ebx
  262.     pop    esi
  263.     pop    edi
  264.     pop    ebp
  265.     ret
  266.  
  267.     public    _asm_resize_bilinear
  268.  
  269. ;**************************************************************************
  270. ;
  271. ;asm_resize_bilinear(
  272. ;    [esp+ 4] void *dst,
  273. ;    [esp+ 8] void *src,
  274. ;    [esp+12] ulong w,
  275. ;    [esp+16] ulong h,
  276. ;    [esp+20] ulong dstpitch,
  277. ;    [esp+24] ulong srcpitch,
  278. ;    [esp+28] ulong xaccum,
  279. ;    [esp+32] ulong yaccum,
  280. ;    [esp+36] ulong xfrac,
  281. ;    [esp+40] ulong yfrac,
  282. ;    [esp+44] long xint,
  283. ;    [esp+48] long yint,
  284. ;    [esp+52] void *srcprecopy,
  285. ;    [esp+56] ulong xprecopy,
  286. ;    [esp+60] void *srcpostcopy,
  287. ;    [esp+64] ulong xpostcopy);
  288. ;
  289. ;**************************************************************************
  290.  
  291.  
  292. _asm_resize_bilinear:
  293.     test    _MMX_enabled,1
  294.     jnz    asm_resize_bilinear_MMX
  295.  
  296.     test    _FPU_enabled,1
  297.     jnz    asm_resize_bilinear_FPU
  298.  
  299.     push    ebp
  300.     push    edi
  301.     push    esi
  302.     push    ebx
  303.  
  304.     sub    esp,32
  305.  
  306.     ;compute y_frac, y_frac2
  307.  
  308.     mov    eax,[esp+32+16+32]
  309.     mov    ebx,16
  310.     shr    eax,28
  311.     mov    [esp+24],eax
  312.     sub    ebx,eax
  313.     mov    [esp+28],ebx
  314.  
  315. ;
  316. ;    [esp+28] y_frac2
  317. ;    [esp+24] y_frac
  318. ;    [esp+20] dest ptr
  319. ;    [esp+16] tstore2
  320. ;    [esp+12] tstore1
  321. ;    [esp+ 8] x_accum
  322. ;    [esp+ 4] x_frac2
  323. ;    [esp+ 0] x_frac
  324.  
  325. rowloop_bilinear:
  326.     mov    ebp,[esp+12+16+32]        ;ebp = -w*4
  327.     mov    eax,[esp+28+16+32]        ;compute x_frac, x_frac2
  328.     mov    ebx,16
  329.     mov    [esp+8],eax
  330.     shr    eax,28
  331.     mov    [esp],eax            ;x_frac
  332.     sub    ebx,eax
  333.     mov    [esp+4],ebx            ;x_frac2 = 16-x_frac
  334.  
  335.     mov    esi,[esp+ 8+16+32]        ;load source ptr
  336.     mov    edx,[esp+4+16+32]        ;load dest pointer
  337.  
  338.     mov    edi,[esp+24+16+32]        ;load source pitch
  339.     mov    [esp+20],edx            ;store dst ptr in temporary
  340.  
  341.     shr    esi,2
  342.     mov    ecx,[esp+56+16+32]        ;load precopy value
  343.     or    ecx,ecx
  344.     jz    colloop_bilinear_start
  345.  
  346.     ;do precopy
  347.  
  348.     push    esi
  349.     mov    esi,[esp+52+16+32+4]
  350.     add    edx,ebp
  351.     mov    [esp+20+4],edx
  352.     mov    ebp,ecx
  353.  
  354.     call    bilinear_prepostcopy
  355.     pop    esi
  356.  
  357.     mov    ebp,[esp+12+16+32]
  358.     mov    edx,[esp+4+16+32]
  359.     mov    [esp+20],edx
  360.  
  361. colloop_bilinear_start:
  362.     or    ebp,ebp
  363.     jz    bilinear_check_postcopy
  364. colloop_bilinear:
  365.     mov    eax,[esi*4]
  366.     mov    ecx,[esi*4+4]
  367.     mov    ebx,eax
  368.     mov    edx,ecx
  369.     and    eax,00ff00ffh
  370.     and    ebx,0000ff00h
  371.     and    ecx,00ff00ffh
  372.     and    edx,0000ff00h
  373.     imul    eax,[esp+4]        ;x_frac2
  374.     imul    ebx,[esp+4]        ;x_frac2
  375.     imul    ecx,[esp]        ;x_frac
  376.     imul    edx,[esp]        ;x_frac
  377.     add    eax,ecx
  378.     add    ebx,edx
  379.     imul    eax,[esp+28]        ;y_frac2
  380.     imul    ebx,[esp+28]        ;y_frac2
  381.     mov    [esp+12],eax        ;tstore1
  382.     mov    [esp+16],ebx        ;tstore2
  383.  
  384.     mov    eax,[esi*4+edi]
  385.     mov    ecx,[esi*4+edi+4]
  386.     mov    ebx,eax
  387.     mov    edx,ecx
  388.     and    eax,00ff00ffh
  389.     and    ebx,0000ff00h
  390.     and    ecx,00ff00ffh
  391.     and    edx,0000ff00h
  392.     imul    eax,[esp+4]        ;x_frac2
  393.     imul    ebx,[esp+4]        ;x_frac2
  394.     imul    ecx,[esp]        ;x_frac
  395.     imul    edx,[esp]        ;x_frac
  396.     add    eax,ecx
  397.     add    ebx,edx
  398.     imul    eax,[esp+24]        ;y_frac
  399.     imul    ebx,[esp+24]        ;y_frac
  400.     add    eax,[esp+12]        ;tstore1
  401.     add    ebx,[esp+16]        ;tstore2
  402.  
  403.     shr    eax,8
  404.     and    ebx,00ff0000h
  405.     shr    ebx,8
  406.     and    eax,00ff00ffh
  407.  
  408.     or    eax,ebx            ;[data write ] u
  409.     mov    edx,[esp+20]        ;[data write ] v
  410.  
  411.     mov    ebx,[esp+8]        ;[frac update] u x_accum
  412.     mov    ecx,[esp+36+16+32]    ;[frac update] v xfrac
  413.  
  414.     mov    [edx+ebp],eax        ;[data write ] u
  415.     add    ebx,ecx            ;[frac update] v: update x_accum
  416.  
  417.     adc    esi,[esp+44+16+32]    ;[frac update] v: update source pointer [2 cycles]
  418.     mov    [esp+8],ebx        ;[frac update] u: store x_accum
  419.  
  420.     shr    ebx,28            ;[frac update] u: x_frac = x_accum>>28
  421.     mov    eax,16            ;[frac update] v:
  422.  
  423.     sub    eax,ebx            ;[frac update] u: x_frac2 = 16 - x_frac
  424.     mov    [esp],ebx        ;[frac update] v: store x_frac
  425.  
  426.     mov    [esp+4],eax        ;[frac update] u: store x_frac2
  427.  
  428.     add    ebp,4
  429.     jne    colloop_bilinear
  430.  
  431. bilinear_check_postcopy:
  432.     mov    ebp,[esp+64+16+32]        ;check for postcopy
  433.     or    ebp,ebp
  434.     jz    bilinear_no_postcopy
  435.  
  436.     push    esi
  437.     mov    esi,[esp+60+16+36]
  438.     sub    edx,ebp
  439.     mov    [esp+20+4],edx
  440.  
  441.     call    bilinear_prepostcopy
  442.     pop    esi
  443.  
  444. bilinear_no_postcopy:
  445.     mov    eax,[esp+32+16+32]        ;load yaccum
  446.     mov    edx,[esp+ 4+16+32]        ;load destination ptr
  447.  
  448.     add    edx,[esp+20+16+32]        ;next destination line
  449.     add    eax,[esp+40+16+32]        ;add yfrac increment to yaccum
  450.  
  451.     sbb    ebx,ebx                ;ebx=-1 if need fractional src increment
  452.     mov    esi,[esp+ 8+16+32]        ;reload source ptr
  453.  
  454.     mov    ecx,[esp+52+16+32]        ;load precopy source ptr
  455.     mov    ebp,[esp+60+16+32]        ;load postcopy source ptr
  456.  
  457.     add    esi,[esp+48+16+32]        ;add integral source increment
  458.     add    ecx,[esp+48+16+32]        ;add integral source increment
  459.     add    ebp,[esp+48+16+32]        ;add integral source increment
  460.     and    ebx,[esp+24+16+32]        ;ebx = fractional src delta
  461.  
  462.     add    esi,ebx                ;add fractional source increment
  463.     add    ecx,ebx                ;add fractional source increment
  464.     add    ebp,ebx                ;add fractional source increment
  465.     mov    [esp+ 4+16+32],edx        ;store destination ptr
  466.     mov    [esp+ 8+16+32],esi        ;store source ptr
  467.     mov    [esp+52+16+32],ecx        ;store source ptr
  468.     mov    [esp+60+16+32],ebp        ;store source ptr
  469.     mov    [esp+32+16+32],eax        ;store yaccum
  470.     shr    eax,28
  471.     mov    ebx,16
  472.     mov    [esp+24],eax
  473.     sub    ebx,eax
  474.     mov    [esp+28],ebx
  475.  
  476.     dec    dword ptr [esp+16+16+32]    ;next line!!
  477.     jne    rowloop_bilinear
  478.  
  479.     add    esp,32
  480.  
  481.     pop    ebx
  482.     pop    esi
  483.     pop    edi
  484.     pop    ebp
  485.     ret
  486.  
  487. bilinear_prepostcopy:
  488.     mov    eax,[esi]
  489.     mov    ecx,[esi+edi]
  490.     mov    ebx,eax
  491.     mov    edx,ecx
  492.     and    eax,00ff00ffh
  493.     and    ebx,0000ff00h
  494.     and    ecx,00ff00ffh
  495.     and    edx,0000ff00h
  496.     imul    eax,[esp+28+8]        ;y_frac2
  497.     imul    ebx,[esp+28+8]        ;y_frac2
  498.     imul    ecx,[esp+24+8]        ;y_frac
  499.     imul    edx,[esp+24+8]        ;y_frac
  500.     add    eax,ecx
  501.     add    ebx,edx
  502.  
  503.     shr    eax,4
  504.     and    ebx,00ff0000h
  505.     shr    ebx,4
  506.     and    eax,00ff00ffh
  507.  
  508.     or    eax,ebx            ;[data write ] u
  509.     mov    edx,[esp+20+8]        ;[data write ] v
  510.  
  511.     mov    [edx+ebp],eax        ;[data write ] u
  512.  
  513.     add    ebp,4
  514.     jne    bilinear_prepostcopy
  515.  
  516.     ret
  517.  
  518. ;
  519. ;
  520. ;******* FPU optimized version.
  521. ;
  522. ;
  523.  
  524. ;real80_adjust    real10    4611686018427387904.0
  525. ;real80_adjust    real10    9223372036854775808.0
  526. ;real80_adjust    real10    13835058055282163712.0
  527. ;real80_adjust    real10    1180591620717411303424.0    ;shift right by 7
  528. real80_adjust    real10    2361183241434822606848.0    ;shift right by 8
  529. real80_adjust16    real10    147573952589676412928.0
  530. ;real80_adjust16    real10     73786976294838206464.0        ;shift right by 4
  531.  
  532. asm_resize_bilinear_FPU:
  533.     push    ebp
  534.     push    edi
  535.     push    esi
  536.     push    ebx
  537.  
  538.     mov    eax,esp
  539.     and    esp,-32
  540.  
  541. LOCALS=96
  542.  
  543.     sub    esp,LOCALS
  544.     mov    [esp+LOCALS-4],eax
  545.  
  546.         ;copy down parameters.
  547.  
  548.     lea    esi,[eax+20]
  549.     lea    edi,[esp+24]
  550.     mov    ecx,16
  551.     rep    movsd
  552.  
  553.     ;flip the FPU into 80-bit, round-down mode.
  554.  
  555.     fstcw    [esp+LOCALS-8]
  556.     mov    eax,[esp+LOCALS-8]
  557.     and    eax,0fffff0ffh
  558.     or    eax,000000700h
  559.     mov    [esp],eax
  560.     fldcw    [esp]
  561.  
  562.     ;prime FPU stack.
  563.  
  564.     fld    real80_adjust
  565.  
  566. ;******************************************************
  567. ;
  568. ;    [esp+ 92] original esp
  569. ;    [esp+ 88] old FP control word
  570. ;    [esp+ 84] xpostcopy
  571. ;    [esp+ 80] srcpostcopy
  572. ;    [esp+ 76] xprecopy
  573. ;    [esp+ 72] srcprecopy
  574. ;    [esp+ 68] yint
  575. ;    [esp+ 64] xint
  576. ;    [esp+ 60] yfrac
  577. ;    [esp+ 56] xfrac
  578. ;    [esp+ 52] yaccum
  579. ;    [esp+ 48] xaccum
  580. ;    [esp+ 44] srcstride
  581. ;    [esp+ 40] dststride
  582. ;    [esp+ 36] height
  583. ;    [esp+ 32] width
  584. ;    [esp+ 28] src
  585. ;    [esp+ 24] dst
  586. ;    [esp+ 20] xaccum'
  587. ;    [esp+ 16] FPU coefficient pointer
  588. ;    [esp+ 12]
  589. ;    [esp+  8]
  590. ;    [esp+  4]
  591. ;    [esp+  0]
  592.  
  593. rowloop_bilinear_FPU:
  594.     mov    ebp,[esp+32]        ;load width count
  595.     mov    eax,[esp+48]        ;copy xaccum
  596.     mov    [esp+20],eax        ;xaccum' = xaccum
  597.  
  598.     mov    edi,[esp+44]        ;load source stride
  599.  
  600.     mov    eax,[esp+52]        ;eax = yaccum
  601.     and    eax,0f0000000h
  602.     shr    eax,20
  603.     add    eax,offset bilinFPU_tbl
  604.     mov    [esp+16],eax
  605.  
  606.     ;check for precopy
  607.  
  608.     mov    ecx,[esp+76]
  609.     or    ecx,ecx
  610.     jz    colloop_bilinear_start_FPU
  611.  
  612.     ;do precopy
  613.  
  614.     mov    edx,[esp+24]
  615.     add    edx,ecx
  616.     mov    ebp,ecx
  617.     mov    [esp+24],edx
  618.     mov    esi,[esp+72]
  619.  
  620.     call    bilinear_prepostcopy_FPU
  621.  
  622.     mov    ebp,[esp+76]
  623.     sub    edx,ebp
  624.     mov    [esp+24],edx
  625.     mov    ebp,[esp+32]
  626.  
  627. colloop_bilinear_start_FPU:
  628.     or    ebp,ebp
  629.     jz    bilinear_check_postcopy_FPU
  630.  
  631.     mov    esi,[esp+28]        ;load source pointer
  632.     mov    bl,[esp+23]        ;cl = xaccum>>24
  633.     shr    esi,2            ;divide source ptr by 4 (!)
  634.     mov    edx,[esp+16]        ;edx = rowbase
  635.     and    ebx,000000f0h        ;ecx = x-offset in rowbase
  636.     add    edx,ebx
  637.  
  638. colloop_bilinear_FPU:
  639.     mov    eax,[esi*4]
  640.     mov    ecx,[esi*4+4]
  641.  
  642.     mov    ebx,eax
  643.     and    eax,00ff00ffh
  644.  
  645.     and    ebx,0000ff00h
  646.     mov    [esp+0],eax
  647.  
  648.     mov    [esp+4],ebx
  649.     mov    ebx,ecx
  650.  
  651.     fild    qword ptr [esp+0]    ;stack: x1 cv
  652.  
  653.     and    ecx,00ff00ffh
  654.     and    ebx,0000ff00h
  655.  
  656.     mov    [esp+8],ecx
  657.     mov    [esp+12],ebx
  658.  
  659.     fmul    real4 ptr [edx+0]    ;stack: y1 cv
  660.     fild    qword ptr [esp+8]    ;stack: x2 y1 cv
  661.  
  662.     mov    eax,[esi*4+edi]
  663.     mov    ecx,[esi*4+edi+4]
  664.  
  665.     mov    ebx,eax
  666.     and    eax,00ff00ffh
  667.  
  668.     fmul    real4 ptr [edx+4]    ;stack: y2 y1 cv
  669.     fxch    st(1)            ;stack: y1 y2 cv
  670.     fadd    st,st(2)        ;stack: (y1+cv) y2 cv
  671.  
  672.     and    ebx,0000ff00h
  673.     mov    [esp+0],eax
  674.  
  675.     mov    [esp+4],ebx
  676.     mov    ebx,ecx
  677.  
  678.     fild    qword ptr [esp+0]    ;stack: x3 (y1+cv) y2 cv
  679.     fxch    st(1)            ;stack: (y1+cv) x3 y2 cv
  680.     faddp    st(2),st        ;stack: x3 (y1+y2+cv) cv
  681.  
  682.     and    ecx,00ff00ffh
  683.     and    ebx,0000ff00h
  684.  
  685.     fmul    real4 ptr [edx+8]    ;stack: y3 (y1+y2+cv) cv
  686.  
  687.     mov    [esp+8],ecx
  688.     mov    [esp+12],ebx
  689.  
  690.     fild    qword ptr [esp+8]    ;stack: x4 y3 (y1+y2+cv) cv
  691.     fxch    st(1)            ;stack: y3 x4 (y1+y2+cv) cv
  692.     faddp    st(2),st        ;stack: x4 (y1+y2+y3+cv) cv
  693.  
  694.     mov    eax,[esp+20]        ;[frac update] u x_accum
  695.     mov    ecx,[esp+56]        ;[frac update] v x_inc
  696.  
  697.     fmul    real4 ptr [edx+12]    ;stack: y4 (y1+y2+y3+cv) cv
  698.  
  699.     mov    ebx,[esp+64]        ;[frac update] u xint
  700.     add    eax,ecx            ;[frac update] v
  701.  
  702.     adc    esi,ebx            ;[frac update] u: update source pointer
  703.     mov    [esp+20],eax        ;[frac update] v new x_accum
  704.  
  705.     fadd                ;stack: (y1+y2+y3+y4+cv) cv
  706.  
  707.     shr    eax,24            ;[frac update] al = xaccum>>24
  708.     mov    edx,[esp+16]        ;[frac update] edx = rowbase
  709.  
  710.     and    eax,000000f0h        ;[frac update] eax = x-offset in rowbase
  711.     mov    ebx,[esp+24]        ;[data write] u
  712.  
  713.     add    edx,eax            ;[frac update] edx = new FPU coefficient pointer
  714.     ;<<v-stall>>
  715.  
  716.     fstp    real10 ptr [esp+0]    ;stack: cv
  717.  
  718.     mov    eax,[esp+0]        ;[data merge ] u
  719.     mov    ecx,[esp+4]        ;[data merge ] v
  720.  
  721.     and    eax,00ff00ffh
  722.     and    ecx,0000ff00h
  723.  
  724.     or    eax,ecx            ;[data write ] u
  725.  
  726.     mov    [ebx+ebp],eax        ;[data write ] u
  727.  
  728.     add    ebp,4
  729.     jne    colloop_bilinear_FPU
  730.  
  731. bilinear_check_postcopy_FPU:
  732.  
  733.     mov    ebp,[esp+84]
  734.     or    ebp,ebp
  735.     jz    bilinear_no_postcopy_FPU
  736.  
  737.     mov    eax,[esp+24]
  738.     sub    eax,ebp
  739.     mov    esi,[esp+80]
  740.     mov    [esp+24],eax
  741.  
  742.     call    bilinear_prepostcopy_FPU
  743.  
  744.     add    edx,[esp+84]
  745.     mov    [esp+24],edx
  746.  
  747.     ;******************
  748.  
  749. bilinear_no_postcopy_FPU:
  750.     mov    eax,[esp+52]        ;load yaccum
  751.     mov    edx,[esp+24]        ;load dest. pointer
  752.  
  753.     add    edx,[esp+40]        ;next destination line
  754.     add    eax,[esp+60]        ;add fractional y increment
  755.  
  756.     sbb    ebx,ebx            ;ebx = -1 if fraction overflowed
  757.     mov    esi,[esp+28]        ;reload source ptr
  758.  
  759.     mov    ecx,[esp+72]        ;reload source ptr
  760.     mov    ebp,[esp+80]        ;reload source ptr
  761.  
  762.     add    esi,[esp+68]        ;add integer increment to source ptr
  763.     add    ecx,[esp+68]        ;add integer increment to source ptr
  764.  
  765.     add    ebp,[esp+68]        ;add integer increment to source ptr
  766.     and    ebx,[esp+44]        ;ebx = fractional y bump
  767.  
  768.     add    esi,ebx            ;bump source ptr if fraction overflowed
  769.     add    ecx,ebx            ;bump source ptr if fraction overflowed
  770.     add    ebp,ebx            ;bump source ptr if fraction overflowed
  771.     mov    [esp+52],eax        ;store yaccum
  772.  
  773.     mov    [esp+28],esi        ;store source ptr
  774.     mov    [esp+72],ecx        ;store source ptr
  775.  
  776.     mov    [esp+80],ebp        ;store source ptr
  777.     mov    [esp+24],edx
  778.  
  779.     dec    dword ptr [esp+36]
  780.     jne    rowloop_bilinear_FPU
  781.  
  782.     ;ditch fp value
  783.  
  784.     fstp    st(0)
  785.  
  786.     ;restore FPU rounding and precision
  787.  
  788.     fldcw    [esp+LOCALS-8]
  789.  
  790.     mov    esp,[esp+LOCALS-4]
  791.  
  792.     pop    ebx
  793.     pop    esi
  794.     pop    edi
  795.     pop    ebp
  796.     ret
  797.  
  798. bilinear_prepostcopy_FPU:
  799.  
  800. colloop_bilinear_prepostcopy_FPU:
  801.     mov    edx,[esp+16+4]        ;edx = rowbase
  802.     mov    eax,[esi]
  803.     mov    ecx,[esi+edi]
  804.  
  805.     mov    ebx,eax
  806.     and    eax,00ff00ffh
  807.  
  808.     and    ebx,0000ff00h
  809.     mov    [esp+0+4],eax
  810.  
  811.     mov    [esp+4+4],ebx
  812.     mov    ebx,ecx
  813.  
  814.     fild    qword ptr [esp+0+4]    ;stack: x1 cv
  815.  
  816.     and    ecx,00ff00ffh
  817.     and    ebx,0000ff00h
  818.  
  819.     mov    [esp+8+4],ecx
  820.     mov    [esp+12+4],ebx
  821.  
  822.     fmul    real4 ptr [edx+0]    ;stack: y1 cv
  823.     fild    qword ptr [esp+8+4]    ;stack: x2 y1 cv
  824.  
  825.     fmul    real4 ptr [edx+8]    ;stack: y2 y1 cv
  826.     fxch    st(1)            ;stack: y1 y2 cv
  827.     fadd    st,st(2)        ;stack: (y1+cv) y2 cv
  828.  
  829.     mov    edx,[esp+24+4]        ;[data write] u
  830.     ;<<v-stall>>
  831.  
  832.     fadd                ;stack: (y1+y2+cv) cv
  833.  
  834.     ;<<u-stall>>
  835.     ;<<v-stall>>
  836.  
  837.     ;<<u-stall>>
  838.     ;<<v-stall>>
  839.  
  840.     fstp    real10 ptr [esp+0+4]    ;stack: cv
  841.  
  842.     mov    eax,[esp+0+4]        ;[data merge ] u
  843.     mov    ecx,[esp+4+4]        ;[data merge ] v
  844.  
  845.     and    eax,00ff00ffh
  846.     and    ecx,0000ff00h
  847.  
  848.     or    eax,ecx            ;[data write ] u
  849.  
  850.     mov    [edx+ebp],eax        ;[data write ] u
  851.  
  852.     add    ebp,4
  853.     jne    colloop_bilinear_prepostcopy_FPU
  854.  
  855.     ret
  856.  
  857. ;
  858. ;
  859. ;******* MMX optimized version.
  860. ;
  861. ;
  862.  
  863. asm_resize_bilinear_MMX:
  864.     push    ebp
  865.     push    edi
  866.     push    esi
  867.     push    ebx
  868.  
  869.     sub    esp,32
  870.  
  871. ;******************************************************
  872. ;
  873. ;    [esp+28]
  874. ;    [esp+24]
  875. ;    [esp+20] y_frac2
  876. ;    [esp+16] y_frac2
  877. ;    [esp+12] y_frac
  878. ;    [esp+ 8] y_frac
  879. ;    [esp+ 4] sixteen
  880. ;    [esp+ 0] sixteen
  881.  
  882.     mov    eax,00100010h
  883.     mov    [esp+0],eax
  884.     mov    [esp+4],eax
  885.  
  886. bilinear_rowloop_MMX:
  887.     mov        esi,[esp+ 8+16+32]        ;esi = source
  888.     mov        edi,[esp+24+16+32]        ;edi = source pitch
  889.  
  890.     mov        edx,[esp+4+16+32]        ;edx = destination
  891.     mov        ebx,[esp+36+16+32]        ;ebx = fractional x increment
  892.     mov        ecx,[esp+44+16+32]        ;ecx = integer x increment
  893.  
  894.     mov        eax,[esp+32+16+32]
  895.     shr        eax,28
  896.     movd        mm7,eax
  897.     punpcklwd    mm7,mm7
  898.     movq        mm6,sixteen
  899.     punpckldq    mm7,mm7
  900.     psubw        mm6,mm7
  901.     pxor        mm5,mm5
  902.  
  903.     shr        esi,2
  904.     mov        eax,[esp+28+16+32]        ;eax = x accumulator
  905.  
  906.  
  907.     mov    ebp,[esp+56+16+32]        ;load precopy value
  908.     or    ebp,ebp
  909.     jz    colloop_bilinear_start_MMX
  910.  
  911.     ;do precopy
  912.  
  913.     add    edx,[esp+12+16+32]
  914.     mov    esi,[esp+52+16+32]
  915.  
  916.     call    bilinear_prepostcopy_MMX
  917.  
  918.     mov    edx,[esp+4+16+32]
  919.     mov    esi,[esp+8+16+32]
  920.  
  921.     shr    esi,2
  922.  
  923. colloop_bilinear_start_MMX:
  924.     mov    ebp,[esp+12+16+32]
  925.     or    ebp,ebp
  926.     jz    bilinear_check_postcopy_MMX
  927.  
  928.     ;<------------- begin pre-entry phase ------------->
  929.  
  930.  
  931.     mov        ecx,eax
  932.     shr        ecx,28
  933.  
  934.     movd        mm0,[esi*4]        ;mm0 = top left pixel
  935.     movd        mm1,[esi*4+4]        ;mm1 = top right pixel
  936.     movd        mm3,[esi*4+edi+4]    ;mm3 = bottom right pixel
  937.     movd        mm2,[esi*4+edi]        ;mm2 = bottom left pixel
  938.     punpcklbw    mm0,mm5
  939.     pmullw        mm0,[bilinMMX_tab2 + ecx*8]
  940.     punpcklbw    mm1,mm5
  941.     pmullw        mm1,[bilinMMX_tab1 + ecx*8]
  942.     punpcklbw    mm2,mm5
  943.     punpcklbw    mm3,mm5
  944.     jmp        short bilinear_colloop_MMX_entry
  945.  
  946.     align        16
  947.  
  948. bilinear_colloop_MMX:
  949.     movd        mm0,[esi*4]        ;mm0 = top left pixel
  950.     paddw        mm4,mm2            ;[last]
  951.  
  952.     movd        mm1,[esi*4+4]        ;mm1 = top right pixel
  953.     psrlw        mm4,8            ;[last]
  954.  
  955.     movd        mm3,[esi*4+edi+4]    ;mm3 = bottom right pixel
  956.     packuswb    mm4,mm4            ;[last]
  957.  
  958.     movd        mm2,[esi*4+edi]        ;mm2 = bottom left pixel
  959.     punpcklbw    mm0,mm5
  960.  
  961.     pmullw        mm0,[bilinMMX_tab2 + ecx*8]
  962.     punpcklbw    mm1,mm5
  963.  
  964.     pmullw        mm1,[bilinMMX_tab1 + ecx*8]
  965.     punpcklbw    mm2,mm5
  966.  
  967.     movd        [edx+ebp-4],mm4        ;[last]
  968.     punpcklbw    mm3,mm5
  969.  
  970. bilinear_colloop_MMX_entry:
  971.     pmullw        mm2,[bilinMMX_tab2 + ecx*8]
  972.     movq        mm4,mm0
  973.  
  974.     pmullw        mm3,[bilinMMX_tab1 + ecx*8]
  975.     paddw        mm4,mm1
  976.  
  977.     add        eax,ebx            ;update x accumulator
  978.     mov        ecx,[esp+44+16+32]
  979.  
  980.     adc        esi,ecx            ;update source address
  981.     pmullw        mm4,mm6
  982.  
  983.     paddw        mm2,mm3
  984.     mov        ecx,eax
  985.  
  986.     shr        ecx,28
  987.     pmullw        mm2,mm7
  988.  
  989.     add        ebp,4
  990.     jnz        bilinear_colloop_MMX
  991.  
  992.     ;<-------------- begin exit phase -------------->
  993.  
  994.     paddw        mm4,mm2            ;[last]
  995.     psrlw        mm4,8            ;[last]
  996.     packuswb    mm4,mm4            ;[last]
  997.     movd        [edx+ebp-4],mm4        ;[last]
  998.     mov        ecx,[esp+44+16+32]
  999.  
  1000.  
  1001. bilinear_check_postcopy_MMX:
  1002.     mov    ebp,[esp+64+16+32]        ;check for postcopy
  1003.     or    ebp,ebp
  1004.     jz    bilinear_no_postcopy_MMX
  1005.  
  1006.     sub    edx,ebp
  1007.     mov    esi,[esp+60+16+32]
  1008.  
  1009.     call    bilinear_prepostcopy_MMX
  1010.  
  1011.     ;********************************
  1012.  
  1013. bilinear_no_postcopy_MMX:
  1014.     mov    eax,[esp+32+16+32]        ;eax = y accumulator
  1015.     mov    edx,[esp+ 4+16+32]        ;reload destination pointer
  1016.  
  1017.     add    edx,[esp+20+16+32]        ;advance to next destination line
  1018.     add    eax,[esp+40+16+32]        ;add y fraction to y accumulator
  1019.  
  1020.     sbb    ebx,ebx                ;ebx = -1 if we have a fractional increment
  1021.     mov    esi,[esp+ 8+16+32]        ;reload source pointer
  1022.  
  1023.     mov    ecx,[esp+52+16+32]        ;reload source pointer
  1024.     mov    ebp,[esp+60+16+32]        ;reload source pointer
  1025.  
  1026.     add    esi,[esp+48+16+32]        ;add y integer increment
  1027.     add    ecx,[esp+48+16+32]        ;add y integer increment
  1028.  
  1029.     add    ebp,[esp+48+16+32]        ;add y integer increment
  1030.     and    ebx,[esp+24+16+32]        ;ebx = y fractional increment
  1031.  
  1032.     add    esi,ebx                ;add y fractional increment
  1033.     add    ecx,ebx                ;add y fractional increment
  1034.     add    ebp,ebx                ;add y fractional increment
  1035.     mov    [esp+ 4+16+32],edx        ;store destination pointer
  1036.  
  1037.     mov    [esp+ 8+16+32],esi        ;store source pointer
  1038.     mov    [esp+52+16+32],ecx        ;store source pointer
  1039.     mov    [esp+60+16+32],ebp        ;store source pointer
  1040.     mov    [esp+32+16+32],eax        ;store new y accumulator
  1041.  
  1042.     shr    eax,28                ;eax = y_frac
  1043.     mov    ebx,16
  1044.  
  1045.     mov    [esp+24],eax            ;store y_frac
  1046.     sub    ebx,eax                ;ebx = y_frac2
  1047.  
  1048.     mov    [esp+28],ebx            ;store y_frac2
  1049.  
  1050.     dec    dword ptr [esp+16+16+32]
  1051.     jne    bilinear_rowloop_MMX
  1052.  
  1053.     add    esp,32
  1054.  
  1055.     pop    ebx
  1056.     pop    esi
  1057.     pop    edi
  1058.     pop    ebp
  1059.     emms
  1060.     ret
  1061.  
  1062.     align        16
  1063. bilinear_prepostcopy_MMX:
  1064.     movd        mm0,[esi]        ;mm0 = top left pixel
  1065.  
  1066.     movd        mm2,[esi+edi]        ;mm2 = bottom left pixel
  1067.     punpcklbw    mm0,mm5
  1068.  
  1069.     punpcklbw    mm2,mm5
  1070.     pmullw        mm0,mm6
  1071.  
  1072.     pmullw        mm2,mm7            ;[last]
  1073.     add        ebp,4
  1074.  
  1075.     paddw        mm0,mm2            ;[last]
  1076.  
  1077.     psrlw        mm0,4            ;[last]
  1078.  
  1079.     packuswb    mm0,mm0            ;[last]
  1080.  
  1081.     movd        [edx+ebp-4],mm0        ;[last]
  1082.     jne        bilinear_prepostcopy_MMX
  1083.  
  1084.     ret
  1085.  
  1086.  
  1087. ;**************************************************************************
  1088. ;
  1089. ;void asm_bitmap_xlat1(
  1090. ;    [esp+ 8] Pixel32 *src,
  1091. ;    [esp+ 4] Pixel32 *dst,
  1092. ;    [esp+16] PixOffset spitch,
  1093. ;    [esp+12] PixOffset dpitch,
  1094. ;    [esp+20] PixDim w,
  1095. ;    [esp+24] PixDim h,
  1096. ;    [esp+28] const Pixel8 *tbl);
  1097. ;
  1098. ;**************************************************************************
  1099.  
  1100.     public    _asm_bitmap_xlat1
  1101.  
  1102. _asm_bitmap_xlat1:
  1103.     push    ebp
  1104.     push    edi
  1105.     push    esi
  1106.     push    ebx
  1107.  
  1108.     mov    esi,[esp+ 8+16]        ;esi = source
  1109.     mov    edi,[esp+ 4+16]        ;edi = destination
  1110.     mov    edx,[esp+28+16]        ;edx = table pointer
  1111. rowloop_xlat1:
  1112.     mov    ebp,[esp+20+16]
  1113.  
  1114. colloop_xlat1:
  1115.     mov    eax,[esi+ebp]        ;fetch pixel
  1116.     xor    ebx,ebx
  1117.  
  1118.     mov    bl,al            ;bl = blue
  1119.     xor    ecx,ecx
  1120.  
  1121.     mov    cl,ah            ;cl = green
  1122.     and    eax,00ff0000h
  1123.  
  1124.     shr    eax,16            ;al = red
  1125.     mov    bl,[edx+ebx]        ;ebx = 000000BB
  1126.  
  1127.     mov    cl,[edx+ecx]        ;cl = translated green
  1128.  
  1129.     shl    ecx,8            ;ecx = 0000GG00
  1130.     mov    al,[edx+eax]        ;al = translated red
  1131.  
  1132.     shl    eax,16            ;eax = 00RR0000
  1133.     or    ecx,ebx            ;ecx = 0000GGBB
  1134.  
  1135.     or    eax,ecx            ;eax = 00RRGGBB
  1136.  
  1137.     mov    [edi+ebp],eax        ;write new pixel
  1138.  
  1139.     add    ebp,4
  1140.     jne    colloop_xlat1
  1141.  
  1142.     add    esi,[esp+16+16]        ;next source row
  1143.     add    edi,[esp+12+16]        ;next dest row
  1144.  
  1145.     dec    dword ptr [esp+24+16]
  1146.     jnz    rowloop_xlat1
  1147.  
  1148.     pop    ebx
  1149.     pop    esi
  1150.     pop    edi
  1151.     pop    ebp
  1152.     ret
  1153.  
  1154. ;**************************************************************************
  1155.  
  1156. ;void asm_bitmap_xlat3(
  1157. ;    [esp+ 4] Pixel32 *dst,
  1158. ;    [esp+ 8] Pixel32 *src,
  1159. ;    [esp+12] PixOffset dpitch,
  1160. ;    [esp+16] PixOffset spitch,
  1161. ;    [esp+20] PixDim w,
  1162. ;    [esp+24] PixDim h,
  1163. ;    [esp+28] const Pixel32 *tbl);
  1164.  
  1165.     public    _asm_bitmap_xlat3
  1166.  
  1167. _asm_bitmap_xlat3:
  1168.     push    ebp
  1169.     push    edi
  1170.     push    esi
  1171.     push    ebx
  1172.  
  1173.     mov    esi,[esp+ 8+16]        ;esi = source
  1174.     mov    edi,[esp+ 4+16]        ;edi = dest
  1175.     mov    edx,[esp+28+16]        ;edx = table pointer
  1176. rowloop_xlat3:
  1177.     mov    ebp,[esp+20+16]
  1178.  
  1179. colloop_xlat3:
  1180.     mov    eax,[esi+ebp]        ;fetch pixel
  1181.     xor    ebx,ebx
  1182.  
  1183.     mov    bl,al            ;bl = blue
  1184.     xor    ecx,ecx
  1185.  
  1186.     mov    cl,ah            ;cl = green
  1187.     and    eax,00ff0000h
  1188.  
  1189.     shr    eax,16            ;al = red
  1190.     mov    ebx,[edx+ebx*4]        ;ebx = xxxxxxBB
  1191.  
  1192.     mov    ecx,[edx+ecx*4]        ;ecx = xxxxGGxx
  1193.     and    ebx,000000ffh        ;ebx = 000000BB
  1194.  
  1195.     mov    eax,[edx+eax*4]        ;eax = xxRRxxxx
  1196.     and    ecx,0000ff00h        ;ecx = 0000GG00
  1197.  
  1198.     or    ecx,ebx            ;ecx = 0000GGBB
  1199.     and    eax,00ff0000h        ;eax = 00RR0000
  1200.  
  1201.     or    eax,ecx            ;eax = 00RRGGBB
  1202.  
  1203.     mov    [edi+ebp],eax        ;write new pixel
  1204.  
  1205.     add    ebp,4
  1206.     jne    colloop_xlat3
  1207.  
  1208.     add    esi,[esp+16+16]        ;next source row
  1209.     add    edi,[esp+12+16]        ;next dest row
  1210.  
  1211.     dec    dword ptr [esp+24+16]
  1212.     jnz    rowloop_xlat3
  1213.  
  1214.     pop    ebx
  1215.     pop    esi
  1216.     pop    edi
  1217.     pop    ebp
  1218.     ret
  1219.  
  1220.     end
  1221.